#include "res_manager.hpp"
#include "logger.hpp"
#include "f_engine.hpp"

#include "zzip/zzip.h"

#include <boost/algorithm/string/replace.hpp>

static const zzip_ssize_t buf_size = 65535;

using namespace std;

boost::shared_ptr<if_system_t> res_manager_t::create(f_engine_t *engine)
{
    boost::shared_ptr<res_manager_t> ret(new res_manager_t(engine));
    logger::log(DEBUG, "[Res Manager] Res Manager system created.");
    return ret;
}

void res_manager_t::start()
{
    engine_->report_started();
}

void res_manager_t::add_res_location(const std::string& location)
{
    string loc(location);

    if (loc.empty())
    {
        throw runtime_error("empty resource location");
    }

    boost::algorithm::replace_all(loc, "\\", "/");

    if (loc[loc.length() - 1] != '/')
    {
        loc += '/';
    }

    logger::log(TRACE) << "[Res Manager] Adding of resource location: " << loc;

    res_locations_.push_back(loc);
}


void res_manager_t::free_res(const std::string &name)
{
    res_map_t::const_iterator it = loaded_resources_.find(name);
    if (it != loaded_resources_.end())
    {
        loaded_resources_.erase(it);
    }
}


bool res_manager_t::is_loaded(const std::string &name)
{
    return loaded_resources_.find(name) != loaded_resources_.end();
}


boost::shared_ptr<stringstream> res_manager_t::make_stream(const std::string &file_path)
{

    ZZIP_FILE *f = zzip_open(file_path.c_str(), 0);

    if (!f)
    {
        return boost::shared_ptr<stringstream>();
    }

    boost::shared_ptr<stringstream> ret(new stringstream);

    char buf[buf_size];

    zzip_ssize_t read = buf_size;
    while (buf_size == read)
    {
        read = zzip_read(f, buf, buf_size);
        ret->write(buf, read);
    };

    zzip_close(f);

    return ret;
}

